// import com.alibaba.druid.sql.ast.SQLParameter;
// import com.alibaba.druid.sql.ast.SQLStatement;
// import com.alibaba.druid.sql.ast.SQLStatementImpl;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "SQLBlockStatement.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../SQLParameter.h"
#include "../../../utils/listTran.h"
#include "../SQLName.h"

SQLBlockStatement::SQLBlockStatement()
{
  parameters = std::make_shared<std::list<SQLParameter_ptr>>();
  statementList = std::make_shared<std::list<SQLStatement_ptr>>();
}

SQLStatement_list_ptr SQLBlockStatement::getStatementList()
{
  return statementList;
}

void SQLBlockStatement::setStatementList(SQLStatement_list_ptr statementList)
{
  this->statementList = statementList;
}

string_ptr SQLBlockStatement::getLabelName()
{
  return labelName;
}

void SQLBlockStatement::setLabelName(string_ptr labelName)
{
  this->labelName = labelName;
}

// @Override
void SQLBlockStatement::accept0(SQLASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(SQLBlockStatement)))
  {
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLParameter, SQLObject>(parameters);
    acceptChild(visitor, tmp1);
    SQLObject_list_ptr tmp2 = ListTran::tran_class<SQLStatement, SQLObject>(statementList);
    acceptChild(visitor, tmp2);
    acceptChild(visitor, exception);
  }
  visitor->endVisit(SharedObject(SQLBlockStatement));
}

SQLParameter_list_ptr SQLBlockStatement::getParameters()
{
  return parameters;
}

void SQLBlockStatement::setParameters(SQLParameter_list_ptr parameters)
{
  this->parameters = parameters;
}

SQLStatement_ptr SQLBlockStatement::getException()
{
  return exception;
}

void SQLBlockStatement::setException(SQLStatement_ptr exception)
{
  if (exception != nullptr)
  {
    exception->setParent(SharedObject(SQLBlockStatement));
  }
  this->exception = exception;
}

string_ptr SQLBlockStatement::getEndLabel()
{
  return endLabel;
}

void SQLBlockStatement::setEndLabel(string_ptr endLabel)
{
  this->endLabel = endLabel;
}

SQLObject_ptr SQLBlockStatement::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<SQLBlockStatement>(new SQLBlockStatement());
  std::shared_ptr<SQLBlockStatement> x = std::dynamic_pointer_cast<SQLBlockStatement>(clone_tmp);
  // SQLBlockStatement x = new SQLBlockStatement();
  x->labelName = labelName;
  x->endLabel = endLabel;

  for (SQLParameter_ptr p : *parameters)
  {
    SQLParameter_ptr p2 = std::dynamic_pointer_cast<SQLParameter>(p->clone());
    p2->setParent(x);
    x->parameters->push_back(p2);
  }

  for (SQLStatement_ptr stmt : *statementList)
  {
    SQLStatement_ptr stmt2 = std::dynamic_pointer_cast<SQLStatement>(stmt->clone());
    stmt2->setParent(x);
    x->statementList->push_back(stmt2);
  }

  if (exception != nullptr)
  {
    x->setException(std::dynamic_pointer_cast<SQLStatement>(exception->clone()));
  }

  return x;
}

SQLParameter_ptr SQLBlockStatement::findParameter(long hash)
{
  for (SQLParameter_ptr param : *this->parameters)
  {
    if (param->getName()->nameHashCode64() == hash)
    {
      return param;
    }
  }

  return nullptr;
}

BOOL_ptr SQLBlockStatement::isEndOfCommit()
{
  return endOfCommit;
}

void SQLBlockStatement::setEndOfCommit(BOOL_ptr value)
{
  this->endOfCommit = value;
}
